home *** CD-ROM | disk | FTP | other *** search
- /*
- * XCopy.cmm
- *
- * An xcopy script for the CEnvi shell. It does what the DOS xcopy
- * command does.
- */
-
- #include "Netware.lib"
-
- usage()
- {
- printf("Use the XCOPY command to selectively copy groups of files.\n");
- printf("Syntax:\n");
- printf(" XCOPY [drive:][path] filename [drive:][path] filename [/S][/E]\n");
- printf(" [/A][/M][/H][/T][/R][/O]\n");
- printf("where:\n");
- printf(" drive:/path/filename Specifies the location of the file to copy.\n");
- printf(" drive:/path/filename Specified the target destination and file name.\n");
- printf(" /S Copies non-empty directories and subdirectories.\n");
- printf(" /E When used with /S, copies entire tree structure,\n");
- printf(" including subdirectories even if they are empty.\n");
- printf(" /A Copies archived files only, but does not turn\n");
- printf(" off the attribute bit of the source file.\n");
- printf(" /M Copies archived files only and turns off the\n");
- printf(" attribute bit of the source file.\n");
- printf(" /H Allows hidden files to be copied to the\n");
- printf(" destination and retain their hidden attribute.\n");
- printf(" /T Allows system files to be copied to the\n");
- printf(" destination and retain their system attribute.\n");
- printf(" /R Allows read-only files to be copied to the\n");
- printf(" destination and retain the read-only attribute,\n");
- printf(" /O Specifies that any read-only, hidden, or system\n");
- printf(" files in the destination can be overwritten by\n");
- printf(" the copy operation.\n");
- exit(EXIT_FAILURE);
- }
-
- /*---------------------------------------------------------------------------*/
-
- recursive = FALSE;
- empty = FALSE;
- archived_only = FALSE;
- turn_off_archived = FALSE;
- copy_hidden = FALSE;
- copy_system = FALSE;
- copy_readonly = FALSE;
- overwrite = FALSE;
- source = "";
- target = "";
-
-
- parse_command_line(argc,argv)
- {
- for( i=1;i<argc;i++ )
- {
- if( argv[i][0]=='-' || argv[i][0]=='/' )
- {
- switch( toupper(argv[i][1]) )
- {
- default: usage(); exit(1);
- case 'S': recursive = TRUE; break;
- case 'E': empty = TRUE;
- case 'M': turn_off_archived = TRUE; // intentional fall-thru
- case 'A': archived_only = TRUE; break;
- case 'H': copy_hidden = TRUE; break;
- case 'T': copy_system = TRUE; break;
- case 'R': copy_readonly = TRUE; break;
- case 'O': overwrite = TRUE; break;
- }
- continue;
- }
- // Else here we have a filename
- if( source[0]=='\0' )
- {
- strcpy(source,argv[i]);
- continue;
- }
- if( target[0]=='\0' )
- {
- strcpy(target,argv[i]);
- continue;
- }
- printf("You may not specify more than one source or target.\n");
- exit(1);
- }
- if( source[0]=='\0' )
- {
- printf("No source file specified.\n");
- exit(1);
- }
- if( target[0]=='\0' )
- {
- printf("No target directory specified.\n");
- exit(1);
- }
- }
-
- /*---------------------------------------------------------------------------*/
-
- DOSTimeFromCalendar(time)
- {
- dos = DOSTimeStructFromCalendar(time);
- return dos.time<<16 | dos.date;
- }
-
- DOSTimeStructFromCalendar(time)
- {
- tm = localtime(time);
- dos.time = (tm.tm_sec/2) | (tm.tm_min<<5) | (tm.tm_hour<<11);
- dos.date = tm.tm_mday | ((tm.tm_mon+1)<<5) | ((tm.tm_year-80)<<9);
- return dos;
- }
-
- GMDOSTimeStructFromCalendar(time)
- {
- tm = gmtime(time);
- dos.time = (tm.tm_sec/2) | (tm.tm_min<<5) | (tm.tm_hour<<11);
- dos.date = tm.tm_mday | ((tm.tm_mon+1)<<5) | ((tm.tm_year-80)<<9);
- return dos;
- }
-
-
- /*
- * Some DOS functions
- */
- SetFileAttributes(pFileName,pAttributes)
- {
- lReg.ah = 0x43;
- lReg.al = 1;
- lReg.cx = pAttributes;
- if !defined(_DOS32_)
- lReg.ds = segment(pFileName), lReg.dx = offset(pFileName);
- else
- lReg.dx = pointer(pFileName);
- return interrupt(0x21,lReg);
- }
-
- SetFileDateAndTime(pFileName,pTime)
- {
- lSuccess = False;
- // Open file to get a handle
- lReg.ah = 0x3D;
- lReg.al = 0x42;
- if !defined(_DOS32_)
- lReg.ds = segment(pFileName), lReg.dx = offset(pFileName);
- else
- lReg.dx = pointer(pFileName);
- if ( interrupt(0x21,lReg,lRegout) ) {
- lHandle = lRegout.ax;
- // write date to file
- undefine(lReg);
- lReg.ah = 0x57;
- lReg.al = 1;
- lReg.bx = lHandle;
- lTm = localtime(pTime);
- lReg.cx = (lTm.tm_sec / 2)
- | (lTm.tm_min << 5)
- | (lTm.tm_hour << 11);
- lReg.dx = lTm.tm_mday
- | ((lTm.tm_mon+1) << 5)
- | ((lTm.tm_year-80) << 9);
- lSuccess = interrupt(0x21,lReg);
- // close file
- undefine(lReg);
- lReg.ah = 0x3E;
- lReg.bx = lHandle;
- interrupt(0x21,lReg);
- }
- return lSuccess;
- }
-
- #define GENERIC_WRITE 0x40000000
- #define FILE_SHARE_READ 0x01
- #define FILE_SHARE_WRITE 0x02
- #define OPEN_EXISTING 3
- #define INVALID_HANDLE_VALUE -1
-
- mymkdir(pDirName) // no return value
- {
- if defined(_OS2_) {
- #define ORD_DOS32CREATEDIR 270
- return !DynamicLink("doscalls",ORD_DOS32CREATEDIR,BIT32,CDECL,pDirName,0)
- } else if ( defined(_NTCON_) || defined(_NTWIN_) ) {
- return !DynamicLink("KERNEL32","CreateDirectoryA",STDCALL,pDirName,NULL);
- } else if( defined(_NWNLM_) )
- {
- return mkdir(pDirName);
- } else { // dos or windows use the same code
- lReg.ah = 0x39;
- if !defined(_DOS32_)
- lReg.ds = segment(pDirName), lREg.dx = offset(pDirName);
- else
- lReg.dx = pointer(pDirName);
- return !interrupt(0x21,lReg);
- }
- }
-
- /* ---------------------------------------------------------------------- */
-
- /*
- * Copy a single file. When done, set the time to the old file's time stamp.
- */
- copy_file(target,source)
- {
- if( (fp = fopen(source,"rb"))==NULL )
- {
- printf("Unable to open source file %s\n",source);
- return;
- }
- if( (fp2 = fopen(target,"wb"))==NULL )
- {
- printf("Unable to open target file %s\n",target);
- fclose(fp);
- return;
- }
-
- buffer = ""; SetArraySpan(buffer,1024);
-
- while( 1 )
- {
- num = fread(buffer,1024,fp);
- if( num<1 ) break;
- fwrite(buffer,num,fp2);
- }
-
- fclose(fp2);
- fclose(fp);
-
- dir = Directory(source);
- if( dir==NULL || GetArraySpan(dir)!=0 )
- {
- printf("Error, can no longer open source file!\n");
- return;
- }
-
- new_attrib = dir[0].attrib;
- if( turn_off_archived ) new_attrib &= ~_A_ARCH;
-
- if( defined(_NWNLM_) )
- {
- tempcreate[0] = DOSTimeFromCalendar(dir[0].Create);
- tempaccess[0] = DOSTimeFromCalendar(dir[0].Access);
- tempdate[0] = DOSTimeFromCalendar(dir[0].Write);
- tempbackup[0] = DOSTimeFromCalendar(dir[0].Backup);
-
- code = NLMLink("SetFileInfo",
- target,
- 0x06,
- new_attrib,
- tempcreate,
- tempaccess,
- tempdate,
- tempbackup,
- dir[0].uid);
-
- if( code )
- printf("\nError setting attributes for file %s\n",target);
- return;
- }
- if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
- {
- SetFileDateAndTime(target,dir[0].Create);
- SetFileAttributes(target,new_attrib);
- return;
- }
- if( defined(_NTCON_) || defined(_NTWIN_) )
- {
- DynamicLink("KERNEL32","SetFileAttributesA",STDCALL,target,dir[0].attrib);
-
- createbuf = ""; SetArraySpan(createbuf,4);
- accessbuf = ""; SetArraySpan(accessbuf,4);
- writebuf = ""; SetArraySpan(writebuf,4);
-
- if( (handle = DynamicLink("KERNEL32","CreateFileA",STDCALL,target,
- GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,OPEN_EXISTING,0,NULL))
- !=INVALID_HANDLE_VALUE)
- {
- dos = GMDOSTimeStructFromCalendar(dir[0].Create);
- DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,createbuf);
- dos = GMDOSTimeStructFromCalendar(dir[0].Access);
- DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,accessbuf);
- dos = GMDOSTimeStructFromCalendar(dir[0].Write);
- DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,writebuf);
-
- if( !DynamicLink("KERNEL32","SetFileTime",STDCALL,handle,createbuf,
- accessbuf,writebuf) )
- {
- err = DynamicLink("KERNEL32","GetLastError",STDCALL);
- printf("Unable to set new file time.\n",err);
- }
-
- if( !DynamicLink("KERNEL32","CloseHandle",STDCALL,handle) )
- printf("Unable to close the handle.\n");
- } else {
- printf("Unable to open the file to touch it.\n");
- }
- return;
- }
-
- if( defined(_OS2_) || defined(_NTCON_) )
- {
- printf("I do not know how to set file attributes on this system.\n");
- exit(EXIT_FAILURE);
- }
- }
-
- /* --------------------------------------------------------------------------- */
-
- get_filename(source)
- {
- filestruct = SplitFileName(source);
- sprintf(newdir,"%s%s",filestruct.name,filestruct.ext);
- return newdir;
- }
-
-
- /*
- * Copy all files from the src directory to the tar directory. Silently create
- * the target directory if it does not already exist. Use the global flags
- * to determine whether to do subdirectories and what to do about special files.
- */
- copy_dir(tar,src)
- {
- printf("Copying directory %s...\n",FullPath(src));
- may_have = 0x3f;
- if( !copy_hidden ) may_have &= ~_A_HIDDEN;
- if( !copy_system ) may_have &= ~_A_SYSTEM;
- if( !copy_readonly )
- {
- may_have &= ~_A_RDONLY;
- if( defined(_NWNLM_) ) may_have |= _A_NORENAM | _A_NODELET;
- }
- must_have = archived_only?_A_ARCH:0;
-
- strcpy(srcfiles,src);
- if( defined(_NWNLM_) )
- strcat(srcfiles,"/*.*");
- else
- strcat(srcfiles,"\\*.*");
-
- files = Directory(srcfiles,FALSE,may_have,must_have);
- if( files==NULL && !empty ) return;
-
- mymkdir(tar);
-
- if( files==NULL ) return;
-
- for( i=0;i<=GetArraySpan(files);i++ )
- {
- if( files[i].attrib & _A_SUBDIR )
- {
- if( recursive )
- {
- strcpy(newname,tar);
- if( newname[strlen(newname)-1]!='/' && newname[strlen(newname)-1]!='\\' )
- {
- if( defined(_NWNLM_) )
- strcat(newname,"/");
- else
- strcat(newname,"\\");
- }
- strcat(newname,get_filename(files[i].name));
- copy_dir(newname,files[i].name);
- }
- } else {
- strcpy(newname,tar);
- if( newname[strlen(newname)-1]!='/' && newname[strlen(newname)-1]!='\\' )
- {
- if( defined(_NWNLM_) )
- strcat(newname,"/");
- else
- strcat(newname,"\\");
- }
- strcat(newname,get_filename(files[i].name));
- copy_file(newname,files[i].name);
- }
- }
- }
-
- /* --------------------------------------------------------------------------- */
-
- main(argc,argv)
- {
- parse_command_line(argc,argv);
-
- tar = Directory(target);
- if( tar==NULL )
- {
- printf("The target does not exist. Assuming you wish to make a new directory\n");
- printf("with that name...\n\n");
- if( mymkdir(target) )
- {
- printf("Unable to make the specified directory.\n");
- exit(1);
- }
- }
-
- copy_dir(target,source);
- }
-